package com.yax.yapi.mainmethod;

import java.io.*;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.*;
import java.util.logging.Logger;

import com.alibaba.fastjson.JSONObject;
import javafx.application.Platform;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.ProgressIndicator;
import org.apache.poi.ss.usermodel.*;

/**
 *
 * 基于POI的读写Excel文件的工具类
 */
public  class ExcelUtils {
    private static Logger log = Logger.getLogger("ExcelUtils");
    private static String xlsPath="D:\\YAPI记录（http接口).xlsx";
    public static void setXlsPath(String xlsPath) {
        ExcelUtils.xlsPath = xlsPath;
    }

    public static String getXlsPath() {
        return xlsPath;
    }

    private static List<List<String>> datas=new ArrayList<>();
    public static List addList(List<String> data){
        datas.add(data);
        return datas;
    }
    private static <T>Field[] getFields(Class<T> clazz,String[] fieldNames) {
        Field[] fs = new Field[fieldNames.length];
        Field[] fields = clazz.getDeclaredFields();
        for (int i = 0; i < fieldNames.length; i++) {
            O:for (Field field : fields) {
                field.setAccessible(true);
                if(field.getName().equals(fieldNames[i])) {
                    fs[i] = field;
                    break O;
                }
            }
        }
        return fs;
    }

    private static <T>String[][] getDatas(String[] titles,List<T> beans,String[] fieldNames) throws Exception{
        List<String[]> datas = new ArrayList<>();

        if(titles != null && titles.length > 0) {
            datas.add(titles);
        }
        //根据List集合中的JavaBean对象的类型，和参数fieldNames，获取要写出的字段数组；
        Field[] fs = getFields(beans.get(0).getClass(),fieldNames);
        for (T t : beans) {
            String[] data = new String[fs.length];
            for (int i = 0; i < fs.length; i++) {
                if(fs[i] != null) {
                    Object obj = fs[i].get(t);
                    String value = obj == null ? "" : obj.toString();
                    data[i] = value;
                }
            }
            datas.add(data);
        }
        return datas.toArray(new String[datas.size()][]);
    }

    public static void writeToExcel(ProgressBar pb, ProgressIndicator pin) throws IOException {
        FileInputStream fileInputStream=null;
        Workbook book =null;
        FileOutputStream fileOutputStream=null;
            try {
                File xls=new File(xlsPath);
                 fileInputStream= new FileInputStream(xls);
                 book = WorkbookFactory.create( fileInputStream);
                 fileOutputStream = new FileOutputStream(xls);
                Sheet sheet = book.getSheetAt(0);
                Map<Integer,CellStyle> cahceStyle=new HashMap<>();
                Row rowt=sheet.getRow(1);
                for(int i=0;i<6;i++){
                    CellStyle cellStyle=rowt.getCell(i).getCellStyle();
                    cahceStyle.put(i,cellStyle);
                }
                int lastRow=2;
                rowt=sheet.getRow(lastRow);
                long start=System.currentTimeMillis();
                while(rowt!=null){
                    Cell cell=rowt.getCell(0);
                    if(cell==null){
                       break;
                    }
                    rowt=sheet.getRow(++lastRow);
                }
                System.out.println("耗时:"+(System.currentTimeMillis()-start));
                log.info("最后行数是"+lastRow+" 数据源"+ JSONObject.toJSONString(datas));
                int count=datas.size();
                for(int i=0;i<datas.size();i++) {
                    // 通过工作表创建行
                    Row row = sheet.getRow(lastRow +i);
                    if (row == null) {
                        row = sheet.createRow(lastRow +i);
                    }
                    for (int j = 0; j < datas.get(i).size(); j++) {
                        // 通过行创建单元格
                        Cell cell = row.getCell(j);
                        if (cell == null) {
                            cell = row.createCell(j);
                        }
                        cell.setCellType(CellType.STRING);
                        // 为单元格设置内容
                        cell.setCellValue(datas.get(i).get(j));
                        cell.setCellStyle(cahceStyle.get(j));
                    }
                    int index=i;
                    Platform.runLater(()->{
                        BigDecimal a=new BigDecimal(index+1);
                        BigDecimal b=new BigDecimal(count);
                        BigDecimal c=a.divide(b,2,BigDecimal.ROUND_HALF_UP);
                        pb.setProgress(c.doubleValue());
                        pin.setProgress(c.doubleValue());
                    });

                }
                book.write(fileOutputStream);
                fileOutputStream.flush();
                datas.clear();
            }catch (Exception e){
               throw e;
            }finally {
                if(fileOutputStream!=null) {
                    fileOutputStream.close();
                }
                if(book!=null) {
                    book.close();
                }
                if(fileInputStream!=null) {
                    fileInputStream.close();
                }
            }
    }

    /**
     * 从指定的Excel的输入流中读取数据，写到指定类型的bean对象的List集合中；
     * @param input：关联到某个Excel文件的输入流
     * @param clazz：要封装一行数据的JavaBean的类型
     * @param fieldNames：一行数据中的列按顺序和JavaBean中对应的字段
     * @return
     * @throws Exception
     */
    public static <T> List<T> readExcel(InputStream input, Class<T> clazz,String[] fieldNames) throws Exception {
        List<T> list = new ArrayList<>();
        Field[] fs = getFields(clazz,fieldNames);
        // 创建一个Workbook对象
        Workbook book = WorkbookFactory.create(input);
        // 通过Workbook对象，获取里面的工作表（sheet对象）
        Sheet sheet = book.getSheetAt(0);
        // 获取工作表中的行
        for (int i = 1; i <= sheet.getLastRowNum(); i++) {
            // 通过行号获取行
            Row row = sheet.getRow(i);
            T t = clazz.newInstance();
            // 遍历获取一行中的所有单元格
            for (int j = 0; j < fs.length; j++) {
                if(fs[j] != null) {
                    Cell cell = row.getCell(j);
                    cell.setCellType(CellType.STRING);
                    setCellValue(fs[j],t,cell);
                }
            }
            list.add(t);
        }
        return list;
    }
    private static void setCellValue(Field field,Object bean,Cell cell) throws Exception {
        String str = cell.toString();
        Class clazz = field.getType();
        if(clazz == byte.class) {
            field.set(bean, Byte.parseByte(str));
        }else if(clazz == short.class) {
            field.set(bean, Short.parseShort(str));
        }else if(clazz == int.class) {
            field.set(bean, Integer.parseInt(str));
        }else if(clazz == long.class) {
            field.set(bean, Long.parseLong(str));
        }else if(clazz == double.class) {
            field.set(bean, Double.parseDouble(str));
        }else if(clazz == float.class) {
            field.set(bean, Float.parseFloat(str));
        }else if(clazz == boolean.class) {
            field.set(bean, Boolean.parseBoolean(str));
        }else {
            field.set(bean, str);
        }
    }
}